﻿using CheemsControl.Animations;
using CheemsControl.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using Path = System.Windows.Shapes.Path;

namespace CheemsControl.Controls
{
    public class LightPieChart : UserControl
    {
        /// <summary>
        /// 数据
        /// </summary>
        public List<SinglePieChartData> Datas
        {
            get { return (List<SinglePieChartData>)GetValue(DatasProperty); }
            set { SetValue(DatasProperty, value); }
        }
        public static readonly DependencyProperty DatasProperty =
            DependencyProperty.Register("Datas", typeof(List<SinglePieChartData>), typeof(LightPieChart), new PropertyMetadata(null, OnDatasChanged));



        public bool IsAnimationEnabled
        {
            get { return (bool)GetValue(IsAnimationEnabledProperty); }
            set { SetValue(IsAnimationEnabledProperty, value); }
        }
        public static readonly DependencyProperty IsAnimationEnabledProperty =
            DependencyProperty.Register("IsAnimationEnabled", typeof(bool), typeof(LightPieChart), new PropertyMetadata(false, OnDatasChanged));



        /// <summary>
        /// 饼图数据改变
        /// </summary>
        /// <param name="d"></param>
        /// <param name="e"></param>
        /// <exception cref="NotImplementedException"></exception>
        private static void OnDatasChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            #region 设置
            double radius = 50.0; // 饼图半径
            double margin = 10;
            #endregion

            LightPieChart thisControl = d as LightPieChart;
            if (thisControl.Datas == null)
            {
                return;
            }
            Grid grid = new Grid();
            Viewbox viewbox = new Viewbox();
            Canvas canvas = new Canvas()
            {
                Width = radius * 2,
                Height = radius * 2,
            };
            #region 统计数据
            double sum = 0;
            for (int i = 0; i < thisControl.Datas.Count; i++)
            {
                sum += thisControl.Datas[i].Value;
            }
            double startValue = 0; // 起始角度
            #endregion

            for (int i = 0; i < thisControl.Datas.Count; i++)
            {
                PieInfo pieInfo = GetPieInfo(startValue, thisControl.Datas[i].Value, sum, radius, margin);
                startValue += thisControl.Datas[i].Value;

                Path path = new()
                {
                    Fill = thisControl.Datas[i].Background,
                    Stroke = thisControl.Datas[i].BorderBursh,
                    StrokeThickness = thisControl.Datas[i].BorderThickness,
                };
                PathGeometry geometry = new PathGeometry();
                PathFigure figure = new PathFigure
                {
                    StartPoint = new Point(pieInfo.centerPoint.Item1, pieInfo.centerPoint.Item2), // 圆心
                    IsFilled = true
                };
                geometry.Figures.Add(figure); // 添加中心点

                // 第一点
                Point firstPointCoords = new Point(pieInfo.startPoint.Item1, pieInfo.startPoint.Item2);
                figure.Segments.Add(new LineSegment(firstPointCoords, true)); // 从圆心到第一点的线
                // 第二点
                Point secondPointCoords = new Point(pieInfo.endPoint.Item1, pieInfo.endPoint.Item2);

                // 添加弧线
                ArcSegment arc = new ArcSegment
                {
                    Point = secondPointCoords,                   // 弧线终点
                    Size = new Size(pieInfo.centerPoint.Item1,pieInfo.centerPoint.Item2), // 弧线的半径
                    SweepDirection = SweepDirection.Clockwise,  // 顺时针绘制
                    IsLargeArc = ((thisControl.Datas[i].Value / sum) > 0.5) // 判断是否为大弧
                };
                figure.Segments.Add(arc);
                // 回到圆心
                figure.Segments.Add(new LineSegment(new Point(pieInfo.centerPoint.Item1, pieInfo.centerPoint.Item2), true));
                // 添加到 Path 的 Data
                path.Data = geometry;
                // 设置样式
                if (thisControl.IsAnimationEnabled)
                {
                    AnimationHelper.ApplyMouseEnterAnimation(path, radius, radius, 1.02); // 鼠标移入控件时控件变大
                }
                path.ToolTip = $"{(string.IsNullOrEmpty(thisControl.Datas[i].Title) ? null : ($"{thisControl.Datas[i].Title}:"))}{thisControl.Datas[i].Value}";
                canvas.Children.Add(path);
            }
            viewbox.Child = canvas;
            grid.Children.Add(viewbox);
            thisControl.Content = grid;
        }

        /// <summary>
        /// 获取饼图信息
        /// </summary>
        /// <param name="startValue"></param>
        /// <param name="value"></param>
        /// <param name="sum"></param>
        /// <param name="radius"></param>
        /// <param name="margin"></param>
        /// <returns></returns>
        private static PieInfo GetPieInfo(double startValue,double value,double sum, double radius = 50.0, double margin = 0)
        {
            PieInfo pieInfo = new PieInfo()
            {
                radius = radius,
            };
            pieInfo.centerPoint = (radius,radius);
            double angleInDegrees = (startValue / sum) * 360.0; // 计算起始角度
            pieInfo.startPoint = GetPiePosition(angleInDegrees, radius); // 起始点
            angleInDegrees += (value / sum) * 360.0; // 计算结束角度
            pieInfo.endPoint = GetPiePosition(angleInDegrees, radius); //结束点


            return pieInfo;
        }


        /// <summary>
        /// 计算边缘点
        /// </summary>
        /// <param name="angleInDegrees">角度</param>
        /// <param name="radius">圆的半径</param>
        /// <returns></returns>
        private static (double, double) GetPiePosition(double angleInDegrees, double radius = 50.0)
        {
            // 将角度转换为弧度
            double angleInRadians = angleInDegrees * Math.PI / 180;
            // 计算正弦和余弦
            double sinValue = Math.Sin(angleInRadians);
            double cosValue = Math.Cos(angleInRadians);

            double x = (1 + sinValue) * radius;
            double y = (1 - cosValue) * radius;

            return (x, y);
        }

    }

    internal class PieInfo
    {
        /// <summary>
        /// 半径
        /// </summary>
        internal double radius {  get; set; }
        /// <summary>
        /// 中心点
        /// </summary>
        internal (double,double) centerPoint {  get; set; }
        /// <summary>
        /// 起始点
        /// </summary>
        internal (double,double) startPoint { get; set; }
        /// <summary>
        /// 结束点
        /// </summary>
        internal (double,double) endPoint { get; set; }
    }
}
